import {ZDragCommonMixin} from "@/plugins/z-dragxml/mixins";
import {QuickBooleanWithNull, QuickEnums} from "@/hooks/props";
import CusGridControl from "@/components/CusGridControl.vue";
CustomVueComponent.registerOnce(CusGridControl)
let ZDragLoopMixin = {
  data() {
    return {
    }
  }
}

function  DRAG_LABEL_XML() {
  return `<div class="z-dragxml-row">
<svg t="1644385766851" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4491" width="16" height="16"><path d="M372.622 746.667c-105.244 0-192-86.756-192-192s86.756-192 192-192c36.978 0 72.534 9.955 103.822 29.866 12.8 8.534 17.067 25.6 8.534 39.823-8.534 12.8-25.6 17.066-39.822 8.533-21.334-14.222-46.934-21.333-72.534-21.333-73.955 0-135.11 61.155-135.11 135.11s61.155 135.112 135.11 135.112 135.111-61.156 135.111-135.111c0-15.645 12.8-28.445 28.445-28.445s28.444 12.8 28.444 28.445c0 105.244-86.755 192-192 192z" p-id="4492"></path><path d="M699.733 746.667c-39.822 0-78.222-11.378-109.51-34.134-12.8-8.533-15.645-27.022-7.112-39.822 8.533-12.8 27.022-15.644 39.822-7.111 22.756 15.644 49.778 24.178 76.8 24.178 73.956 0 135.111-61.156 135.111-135.111s-61.155-135.111-135.11-135.111-135.112 61.155-135.112 135.11c0 15.645-12.8 28.445-28.444 28.445s-28.445-12.8-28.445-28.444c0-105.245 86.756-192 192-192s192 85.333 192 192c0 105.244-86.755 192-192 192z" p-id="4493"></path></svg>
<div class="z-dragxml-label__name">无限层</div>
</div>`
}


/**
 *
 * @param options
 * @returns {string}
 */
export function createZDragLoopTemplate(options = {}) {
  return `
    <div class="z-dragxml-com z-drag-loop ${options.cls}" :class="[{['z-dragxml-loop--table']: widgetMode === 'table'}, customCls]"
  no-drag-line
  @dragenter.prevent.stop="onDragEnter"
  @mouseenter.stop="onMouseEnter"
  :z-drag-loop-uuid="uuid"
  >
  <!--    {{uuid}}-->
<!--      {{ui_config_editor}}-->
  <!--    <div>{{FIND_ARR_TYPE('level' + level)}}</div>-->
  <div class="z-dragxml-com__header">
  <div class="z-dragxml-com__title" style="color: var(--el-color-primary)">{{zdrag__GET_CONFIG('ui.defTypeName') || FIND_ARR_TYPE('未定义类型')}}</div>
  <div class="z-dragxml-com__action">${options.actionXml ?? ''}</div>
  </div>
  <div class="z-dragxml-loop__con" >

    <!--    <z-drag-loop v-if="level < 1" :level="level + 1"></z-drag-loop>-->
    <div :id="zdrag_loop__genId(startUUID)" class="z-dragxml-loop__start"
    @dragenter.stop="zdrag_loop__onDragEnterStart(startUUID, $event)"
    >&nbsp;</div>
  <!--    {{widgets}}-->
 <div ${options.conXml ?? ''}>
   <div :id="zdrag_loop__genId(widget[0])" class="z-dragxml-loop__item" :class="[customCls + '__item']"
  v-for="widget in widgets" :key="widget[0]"
  @dragenter.stop="zdrag_loop__onDragEnter(widget, $event)"

  >
  <!--      {{widget}}-->
  <component
  :is="widget[0]" :ref="widget[0]" v-if="widget && widget[0]"></component>
</div>
</div>
<div :id="zdrag_loop__genId(endUUID)" class="z-dragxml-loop__end"
@dragenter.stop="zdrag_loop__onDragEnterEnd(endUUID, $event)"
@dragleave.stop="zdrag_loop__onDragLeaveEnd"
  >&nbsp;</div>

</div>
<div class="z-drag-loop__append"
     v-if="ui_config_editor && ui_config_editor.ins && ui_config_editor.ins.ui && ui_config_editor.ins.ui.defType === 'arrayObj'"
>
  <el-space>
    <el-button>新增一项</el-button>
  </el-space>
</div>
</div>
  `
}

/**
 * 拖拽容器的通用初始化方法
 * @param entiels
 * @param resolveData
 * @param disabledDrag
 * @returns {{components: {}, ZDragCusExport: boolean, data(): *, DRAG_LOOP: boolean, created(): void, methods: {DRAG_BUILD_TREE(): [{tree_id, label_xml, label, id}], onZDragXmlDropEnd(*, *): void, onMouseEnter(*): void, deleteWidgetByUUID(*): (boolean), zdrag_loop__genId(*): *, onDragEnter(*): void, private_set_drag_context(): void, private_checkMyIsInOtherZdragLoop(): (*|string), checkIsTopZDragLoop(): boolean, getParetntZDragLoop(): *, zdrag_loop__onDragEnter(*, *): void, handleDragXmlButtonDelete(*): void, zdrag_loop__highlight(*): void, DRAG_LABEL_XML(): string, private_insertWidget(*): void, private_initWidget(*, *=): void, zdrag_loop__onDragEnterEnd(*): void, private_append_widget(*=, {handleObj: *}=): void, private_delete_widget(*): (boolean), private_getWidgetIndex(*): number, zdrag_loop__onDragLeaveEnd(), zdrag_loop__onDragEnterStart(*, *): void, FIND_ARR_TYPE(*): (string), deleteSubZdragLoop(*, *): void, handleDragXmlDelete(*, *=): void, deleteAllWidgets(*): void}, ZDragXmlCom: boolean, ZDragExp: boolean, props: {defType: {default: string, type: StringConstructor}, level: {default: number, type: NumberConstructor}}, mixins: {beforeUnmount(): void, mixins: [{beforeUnmount(): void, data(): {_zdrag__setCurHighLightUUID: string}, methods: {zdrag__highlight_cls(*, *): {"z-drag-highlight": boolean}, private__onHighlightChanged(*): void}, inject: [string], mounted(): void}], emits: [string], data(): {cus_ref: null, ui_form_config: *, ui_config_editor, isHighlight: boolean, ui_cached: {common: {}}, locked: boolean, v2: string}, computed: {cus_config(): *, form_config(): *, zdrag__cus_config(): *, zdrag__form_config(): *}, methods: {private__handle_zlayoutinit(): void, zdrag__state_cls(): {"z-dragxml--is-highlight": boolean}, onFormConfigChanged(): void, handleDragXmlButtonClick(*): void, onConfigChanged(): void, zdrag__highlight(): *, handleDragXmlButtonDelete(*): void, zdrag__onMouseEnter(*): void, zdrag__GET_CONFIG(*, *): *, zdrag__get_cus_ref(*): void}, beforeMount(): void, inject: string[], mounted(): void, props: {layout_uuid: String | StringConstructor, uuid: String | StringConstructor}}[], provide(): {ZDragLoopIns: {level: *}}, DRAG_CONFIG(): {}, DRAG_LABEL_XML(): string, DRAG_PANEL_CLS: string, inject: string[], DRAG_UI_CONFIG(): {isCustomRender: {ui: {label: string, widgetConfig: {ext: string}}, rules: {type: string}, type: string}, defType: {ui: {widget: string, widgetConfig: {mode: string, suggest: ({label: *, value: *}|*)[]}}, type: string}, tag: {ui: {widget: string, widgetConfig: {mode: string, suggest: ({label: *, value: *}|*)[]}}, type: string}}, DRAG_DATASET(): {columnMax: number}}|{isCustomRender: {ui: {label: string, widgetConfig: {ext: string}}, rules: {type: string}, type: string}, defType: {ui: {widget: string, widgetConfig: {mode: string, suggest: ({label: *, value: *}|*)[]}}, type: string}, tag: {ui: {widget: string, widgetConfig: {mode: string, suggest: ({label: *, value: *}|*)[]}}, type: string}}|{ZDragLoopIns: {level: number}}|{}|{tree_id, label_xml, label, id}[]|string|*|number|boolean|{columnMax: number}}
 */
export function createZDragLoopDef(
  {
    /**
     * 类型
     */
    entiels = [
    // ['对象', 'obj'],
      ['数组对象', 'arrayObj'],
    ['GRID', 'grid'],
    ],
    /**
     * 处理data
     * @type {Function}
     */
    resolveData = function (r) {return r},
    /**
     * 是否禁用拖拽
     * @type {Boolean}
     */
    disabledDrag = false
  } = {}
) {
  // console.log('entiels', entiels)
  return {
    components: {},
    DRAG_LOOP: true,
    DRAG_PANEL_CLS: 'panel__z-drag-loop',
    ZDragXmlCom: true,
    ZDragExp: true,
    ZDragCusExport: true,
    inject: ['ZDragxmlInstance'],
    mixins: [
      ZDragCommonMixin
    ],
    props: {
      level: {
        type: Number,
        default: 0
      },
      defType: {
        type: String,
        default: ''
      }
    },
    DRAG_CONFIG() {
      return {
      }
    },
    DRAG_UI_CONFIG() {
      let defType = QuickEnums(entiels)
      defType.ui.label = '定义类型'
      defType.ui.widgetConfig.readonly = true
      defType.ui.widgetConfig.placement = 'top'
      defType.ui.class = [
        'zdragxml__prop__loop_l1'
      ]

      let isCustomRender = QuickBooleanWithNull('自定义渲染', {
        ui: {
          class: [
            'zdragxml__prop__loop_l1'
          ]
        }
      })

      let tag = QuickEnums(
          [
            {
              label: '数据表格',
              value: 'z-data-arr',
            },
          ]
        )

      tag.ui.label = '自定义标签'
      tag.ui.widgetConfig.placement = 'top'
      tag.ui.class = [
          'zdragxml__prop__loop_l1'
        ]

      return {
        isCustomRender,
        tag,
        defType,
      }
    },
    DRAG_DATASET() {
      return {
        // exp: 1,
        columnMax:2
      }
    },
    DRAG_LABEL_XML() {
      return DRAG_LABEL_XML()
    },
    provide() {
      return {
        ZDragLoopIns: {
          level: this.level
        },
      }
    },
    data() {
      let d = resolveData({
        id: ZY.rid(6),
        ui: {
          layout: true,
          widgetConfig: {
            // type: 'textarea'
          }
        },
        widgetUUID: '',
        // def: {},
        dragEnterStart: false,
        dragEnterEnd: false,
        // meta: {},
        startUUID:  ZY.rid(6) + '__start',
        endUUID:  ZY.rid(6) + '__end',
        widgets: [],
        dragEnterWidget: [],
        IS_ZRAG_LOOP: true,
        widgetMode: '',
        customCls: 'z-drag-loop--uni-' + ZY.rid(6)
      })
      if (!d.INIT_CONFIG) {
        d.INIT_CONFIG = {}
      }
      if (this.defType) {
        if (!d.INIT_CONFIG.ui) {
          d.INIT_CONFIG.ui = {}
        }
        d.INIT_CONFIG.ui.defType = this.defType
        d.INIT_CONFIG.ui.GRID_ITEM = true
      }
      console.log('zdragloop created',  d)
      return d
    },
    created() {
      let self = this

      // 避免zdrag__loop没有field_name
      this.ZDragxmlInstance.updateConfig(this.uuid, function (config) {
        // console.log(config, self.INIT_CONFIG)
        if (config && !config?.ins?.server?.field_name) {
          ZY.lodash.set(config, 'ins.server.field_name', 'loop__' + ZY.rid(6))
        }
      }, function (config) {
        config.ins = self.INIT_CONFIG ?? {}
        self.ui_config_editor = config
      })
      // console.log(self.private_initWidget)
       setTimeout(() => {
         self.ZDragxmlInstance.setMemosCtx(self.uuid, {
           ctx: self,
           toMemo() {
             return {
               widgets: self.widgets
             }
           },
           fromMemo(data) {
             // self.widgets = data.widgets
             // console.log(data)
             ZY.lodash.each( data.widgets ,  function (item, key) {
               let value = item[1]
               self.private_initWidget(item[0], value)
               self.widgets.push(item)
             })
           }
         });
         if (self.onCreated) {
           self.onCreated();
         }
       }, 30)
    },
    methods: {
      DRAG_LABEL_XML() {
        return DRAG_LABEL_XML()
      },
      FIND_ARR_TYPE(defaultVal) {
        // console.log(this.ui_config_editor)
        let defType =  ZY.lodash.get( this.ui_config_editor, 'ins.ui.defType')
        if (defType) {
          let o = entiels.find(v => {
            return v[1] === defType
          })
          if (o) {
            return o[0]
          }
        }
        return defaultVal
      },
      DRAG_BUILD_TREE() {
        let self = this
        let ZDragLoopDef = CustomVueComponent.resolve('ZDragLoop')
        let level0 = self.ZDragxmlInstance.buildTreeMenuItermStruct(
          ZDragLoopDef.name, self.uuid, DRAG_LABEL_XML(), ZDragLoopDef)
        // console.log(level0)
        level0.layout_uuid = self.layout_uuid
        // console.log(this.widgets)
        let children = []
        this.widgets.forEach(([widgetUUID, widgetDef]) => {
          let comDef = CustomVueComponent.resolve(widgetDef.comName)
          let obj = self.ZDragxmlInstance.buildTreeMenuItermStruct(
            widgetDef.comName, widgetDef.uuid, comDef.DRAG_LABEL_XML(), comDef)
          obj.root_id = self.uuid
          obj.zdrag_loop_options = {
            widgetUUID,
          }
          // console.log(comDef)
          if (comDef.DRAG_LOOP) {
            let subZdragContext = self.ZDragxmlInstance.getRegisterCtx(widgetDef.uuid)
            if (subZdragContext && subZdragContext.DRAG_BUILD_TREE) {
              let tree = subZdragContext.DRAG_BUILD_TREE()
              // console.log(obj, tree)
              // children.push(tree)
              // obj.children = tree.children
              children.push(tree[0])
            }
          } else {
            children.push(obj)
          }
        })
        level0.children = children
        return [
          level0
        ]
      },
      onDragEnter(e) {
        // console.log('onDragEnter',e, this.ZDragxmlInstance)
        this.isInDragOver = true
      },
      onMouseEnter(e) {
        this.ZDragxmlInstance.onMouseEnter2(
          e.target,
          {
            itemUUID: this.uuid,
            ctx: this
          }
        )
      },
      /**
       * 检测自己是否是第一级
       * @returns {boolean}
       */
      checkIsTopZDragLoop() {
        let el = this.$el
        return !el.hasAttribute('data-context-uuid')
      },
      getParetntZDragLoop() {
        let el = this.$el
        let uuid =  el.getAttribute('data-context-uuid')
        return this.ZDragxmlInstance.getRegisterCtx(uuid)
      },
      deleteWidgetByUUID(uuid) {
        let index = this.widgets.findIndex(v => v[1].uuid === uuid)
        if (index > -1) {
          // console.log(index)
          this.widgets.splice(index, 1)
          return true
        }
        return false
      },
      private_delete_widget(widgetName) {
        // if (Array.isArray(this.widgets) && this.widgets.length < 1) {
        //   return true
        // }
        let index = this.widgets.findIndex(v => v[0] === widgetName)
        if (index > -1) {
          // console.log(index)
          this.widgets.splice(index, 1)
          return true
        }
        return false
      },

      handleDragXmlDelete(data, options = {}) {
        // console.log('handleDragXmlDelete', data)
        let zdrag_loop_options = data.zdrag_loop_options
        if (zdrag_loop_options) {
          this.private_delete_widget(zdrag_loop_options.widgetUUID)
          options.clearConfigByID(data.itemUUID)
          options.reloadTree()
        }
      },
      private_checkMyIsInOtherZdragLoop() {
        if (this?.$parent?.$parent) {
          let parentZDragLoop =  this?.$parent?.$parent
          if (parentZDragLoop.IS_ZRAG_LOOP) {
            // console.log(this.$parent)
            let hostZDragLoop = this?.$parent
            let dataLoopName = hostZDragLoop.$el.getAttribute('data-loop-name')
            if (parentZDragLoop.widgets ) {
              let keys = parentZDragLoop.widgets.map(v => v[0])
              if (keys.includes(dataLoopName)) {
                console.log('你一定想删除里面的zdragLoop')
                return dataLoopName
              }
            }
            // console.log(parentZDragLoop.widgets, dataLoopName)
          }
        }
        return ''
      },
      /**
       * 删除所有子元素 碰到zdragLoop继续删除子元素
       * @param clearConfigByID
       */
      deleteAllWidgets(options) {
        // 删除子元素
        let self = this
        if (Array.isArray(this.widgets)) {
          self.widgets.forEach(([widgetName, widgetDef]) => {
            // options.clearConfigByID(widgetDef.ctx.uuid)
            let widgetContext = self.ZDragxmlInstance.getRegisterCtx(widgetDef.uuid)
            if (widgetContext) {
              // console.log(widgetContext)
              if (widgetContext.IS_ZRAG_LOOP) {
                widgetContext.deleteAllWidgets(options)
              }
              else {
                options.clearConfigByID(widgetDef.uuid)
              }
            }
            // options.clearConfigByID(widgetDef.uuid)
            // console.log(widgetContext)
          })
          self.widgets = []
        }
      },
      handleDragXmlButtonDelete(options) {
        let self = this
        let trueDom = options.trueDom
        let widgetName = trueDom.getAttribute('data-loop-name')
        let isDelete = this.private_delete_widget(widgetName)
        if (isDelete) {
          options.clearConfigByID(options.ctx.uuid)
          options.reloadTree()
        } else {
          console.log('然道你嵌套了zdragloop', this)
          let isInOtherXZdragLoop = this.private_checkMyIsInOtherZdragLoop()
          if (Array.isArray(this.widgets)) {
            this.widgets.forEach(([widgetName, widgetDef]) => {
              // options.clearConfigByID(widgetDef.ctx.uuid)
              let widgetContext = self.ZDragxmlInstance.getRegisterCtx(widgetDef.uuid)
              if (widgetContext) {
                options.clearConfigByID(widgetDef.uuid)
              }
              console.log(widgetContext, widgetDef)
            })
            this.widgets = []
          }
          if (isInOtherXZdragLoop) {
            let parentZDragLoop =  this?.$parent?.$parent
            // console.log(this.$refs)
            options.clearConfigByID(options.ctx.uuid)
            parentZDragLoop.deleteSubZdragLoop(isInOtherXZdragLoop, this)
            options.reloadTree()
          }
        }
        // console.log(options, widgetName, trueDom)
      },
      deleteSubZdragLoop(widgetUUID, subZDragLoopContext) {
        // console.log(widgetUUID)
        this.private_delete_widget(widgetUUID)
      },
      private_append_widget(comName = '', {handleObj} = {}) {
        let widgetName = this.uuid + '__' + ZY.rid(6)

        let self = this

        let uuid=  'ZDragLoop__child__' + ZY.rid(6)
        let cur = [
          widgetName,
          {
            // def,
            uuid,
            data: {
              uuid,
              level: self.level + 1
            },
            comName
          }
        ]
        let obj = cur[1]
        if (handleObj) {
          obj = handleObj(obj)
        }
        this.private_initWidget(cur[0], obj)
        this.private_insertWidget(cur)
        this.ZDragxmlInstance.clearLineInspect()
        this.ZDragxmlInstance.setCurrentDragEnterContext(
          null
        )
      },
      onZDragXmlDropEnd(com, trueDom) {
        // console.log('onZDragXmlDropEnd', com, trueDom, this.isInDragOver)
        this.isInDragOver = false
        this.private_append_widget(com.name)
        setTimeout(() => {
          this.ZDragxmlInstance.reloadTreeMenu()
        }, 150)
      },
      /**
       * 获取widget在当前index
       * @param widget
       * @returns {number}
       */
      private_getWidgetIndex(widget) {
        return this.widgets.findIndex(v => v[0] === widget[0])
      },
      private_insertWidget(cur) {
        if (this.dragEnterStart) {
          this.dragEnterStart = false
          this.widgets.unshift(cur)
          return
        }
        if (this.dragEnterEnd) {
          this.dragEnterEnd = false
          this.widgets.push(cur)
          return
        }
        if (this.dragEnterWidget && this.dragEnterWidget[0]) {
          let index = this.private_getWidgetIndex(this.dragEnterWidget)
          // console.log(index)
          this.widgets.splice(index + 1, 0, cur)
        } else {
          this.widgets.push(cur)
        }
      },
      private_initWidget(widgetName, obj = { comName: '', afterAttr: ''}) {
        let self = this
        let comName = obj.comName
        let def = {
          name: widgetName,
          template: `<${comName} data-context-uuid="${self.uuid}"
data-loop-name="${widgetName}"
:uuid="uuid" :level="level" ${obj.afterAttr}></${comName}>`,
          mixins: [
            ZDragLoopMixin
          ],
          data() {
            return obj.data
          },
        }
        globalThis.CustomDymComponent.register(def)
      },
      zdrag_loop__highlight(uuid) {
        let dom  = document.getElementById(uuid)
        if (dom) {
          this.ZDragxmlInstance.createLineInspect(dom)
          this.ZDragxmlInstance.clearTest1LineInspect()
        }
      },
      private_set_drag_context() {
        this.ZDragxmlInstance.setCurrentDragEnterContext(
          this
        )
      },
      zdrag_loop__onDragEnterStart(uuid, e) {
        if (disabledDrag) {
          return
        }
        this.dragEnterStart = true
        this.private_set_drag_context()
        this.zdrag_loop__highlight(uuid)
      },
      zdrag_loop__onDragEnterEnd(uuid) {
        if (disabledDrag) {
          return
        }
        this.dragEnterEnd = true
        this.private_set_drag_context()
        this.zdrag_loop__highlight(uuid)
        // console.log('zdrag_loop__onDragEnterEnd')
      },
      zdrag_loop__onDragLeaveEnd() {
        // this.ZDragxmlInstance.clearCurrentDragEnterContext()
        // this.ZDragxmlInstance.clearAllTestToolsInspect()
      },
      zdrag_loop__onDragEnter(widget, e) {
        // console.log('zdrag_loop__onDragEnter', widget, e.target)
        if (disabledDrag) {
          return
        }

        this.dragEnterStart = false;
        this.dragEnterEnd = false;
        this.private_set_drag_context()

        let index = this.private_getWidgetIndex(widget)
        // console.log(index, this.widgets.length)
        if (index > this.widgets.length - 2) {
          return ;
        }

        this.dragEnterWidget = widget
        this.zdrag_loop__highlight(widget[0])
      },

      zdrag_loop__genId(id) {
        return id
      }
    }
  }
}
